package com.fingard.dsp.bank.directbank.cmbc02;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.seq.SeqData;
import com.fingard.dsp.bank.dbobj.seq.SeqDataHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IContract;
import com.fingard.dsp.bank.reqrespobj.contract.*;
import com.fingard.dsp.bank.reqrespobj.contract.detail.RetAtsContractDetail;
import com.fingard.text.StringHelper;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 民生收付易签约
 * <p>
 * 参考文档:【直连测试】中国民生银行_收付易商户直连接口文档v1.1.5.2.xls
 * 开发接口：
 * 1、白名单申请(PAY_T016)
 * 2、白名单短信验证(PAY_T017)
 *
 * @author Cruise
 * @date 2019/3/5
 */
public class CMBC02Contract extends CMBC02Base implements IContract {
    @SuppressWarnings("unchecked")
    @Override
    public RetAtsContract contract(ReqContract p_req) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_req.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_req.contractDetail.askNumber;
        SeqDataHelper seqHelper = null;
        try {
            seqHelper = new SeqDataHelper(p_req.reqHeader.tenant, new Date());
            ActSetItem actItem = getBankConfig().getActSetItem(p_req.contractDetail.recAct, "");
            if (actItem != null) {
                String postscript = p_req.contractDetail.memo;

                if (StringHelper.isNullOrEmpty(postscript)) {
                    String defPostscript = this.getBankConfig().getValueAsString("defContractPostscript");
                    if (StringHelper.hasAnyChar(defPostscript)) {
                        postscript = defPostscript;
                    }
                }
                String merchantSeq = p_req.contractDetail.askNumber;
                boolean padSingleSeq50 = getBankConfig().getValueAsBool("padSingleSeq50");
                this.WriteBankLogLn("padSingleSeq50:"+padSingleSeq50);
                if ("01".equals(p_req.contractDetail.step)) {
                    if(padSingleSeq50){
                        merchantSeq = actItem.merchantId+"_"+merchantSeq+"_";
                        merchantSeq = StringHelper.padByByte(merchantSeq, this.getCharset(reqHeader.transType), 50, '0', 'R');
                    }
                    String version = "v1.0";
                    String source = "PC";
                    String merchantNum = actItem.merchantId;
                    Date timeNow = new Date();
                    String transDate = Format.Date8Format.format(timeNow);
                    String transTime = Format.Time9Format.format(timeNow);
                    String transCode = "PAY_T016";
                    String securityType = "SM203";
                    String reserve1 = "";
                    String reserve2 = "";
                    String reserve3 = "";
                    String reserve4 = "";
                    String reserve5 = "";
                    String reserveJson = "";
                    // 业务报文 businessContext String 4096 N 传递给业务系统的报文

                    // 组装业务报文
                    String defaultTradeType = "30010001";
                    String contractId = actItem.getBusCode("auth");
                    String inaterContractIdList = actItem.getBusCode("auth");
                    String acctType = "";
                    String cardType = p_req.contractDetail.cardType;
                    //付款帐号类型（0-对公 1-卡 2-折）
                    //1：存折，2：借记卡，3：信用卡
                    if ("2".equals(cardType)) {
                        acctType = "1";
                    } else if ("1".equals(cardType)) {
                        acctType = "2";
                    } else {
                        acctType = "0";
                    }
                    String draweeAccNo = p_req.contractDetail.payAct;
                    String draweeAccName = p_req.contractDetail.payName;
                    String draweePartyId = "";
                    String draweePhoneNum = p_req.contractDetail.cellPhone;
                    String draweeCertType = convertCertTypeToBank(p_req.contractDetail.certType);
                    String draweeCertNo = p_req.contractDetail.certNum;
                    String startDate = transDate;
                    String endDate = p_req.contractDetail.deadLine;
                    if (StringHelper.isNullOrEmpty(endDate)) {
                        endDate = getBankConfig().getValueAsString("deadLine");
                    }
                    String limitAmt = "";
                    String smFlag = "1";
                    String ctrlFlag = "11";
                    String chkType = "3";
                    String extendData = "";
                    // 发送给银行的报文
                    Map<String, String> messagetoBank = new HashMap<String, String>();
                    messagetoBank.put("version", version);
                    messagetoBank.put("source", source);
                    messagetoBank.put("merchantNum", merchantNum);
                    messagetoBank.put("merchantSeq", merchantSeq);
                    messagetoBank.put("transDate", transDate);
                    messagetoBank.put("transTime", transTime);
                    messagetoBank.put("transCode", transCode);
                    messagetoBank.put("securityType", securityType);
                    messagetoBank.put("reserve1", reserve1);
                    messagetoBank.put("reserve2", reserve2);
                    messagetoBank.put("reserve3", reserve3);
                    messagetoBank.put("reserve4", reserve4);
                    messagetoBank.put("reserve5", reserve5);
                    messagetoBank.put("reserveJson", reserveJson);
                    messagetoBank.put("defaultTradeType", defaultTradeType);
                    messagetoBank.put("contractId", contractId);
                    messagetoBank.put("inaterContractIdList", inaterContractIdList);
                    messagetoBank.put("acctType", acctType);
                    messagetoBank.put("draweeAccNo", draweeAccNo);
                    messagetoBank.put("draweeAccName", draweeAccName);
                    messagetoBank.put("draweePartyId", draweePartyId);
                    messagetoBank.put("draweePhoneNum", draweePhoneNum);
                    messagetoBank.put("draweeCertType", draweeCertType);
                    messagetoBank.put("draweeCertNo", draweeCertNo);
                    messagetoBank.put("startDate", startDate);
                    messagetoBank.put("endDate", endDate);
                    messagetoBank.put("limitAmt", limitAmt);
                    messagetoBank.put("smFlag", smFlag);
                    messagetoBank.put("ctrlFlag", ctrlFlag);
                    messagetoBank.put("chkType", chkType);
                    messagetoBank.put("extendData", extendData);
                    messagetoBank.put("postscript", postscript);

                    Map<String, String> submitMap = new HashMap<String, String>();
                    Map<String, String> busiMap = new HashMap<String, String>();
                    splidReqMap(messagetoBank, submitMap, busiMap);
                    submitMap.put("businessContext", encodeMsgToString(p_req.contractDetail.recAct, busiMap));
                    String message = submitMap.toString();
                    WriteBankLogLn("发送给银行的报文：" + message);
                    String tmpUrl = bankFront.getUrl("Pay");
                    String[] tmpStrRet = sendToBank(submitMap, tmpUrl);
                    if (tmpStrRet[0].length() == 0) {
                        WriteBankLogLn("银行返回的报文：" + tmpStrRet[1]);
                        Map<String, String> reMap = (Map<String, String>) JSON.parse(tmpStrRet[1].toString());
                        WriteBankLogLn("解析后银行返回的报文map形式：" + reMap);
                        WriteBankLogLn("解析后银行返回的报文：" + reMap.toString());
                        String gateReturnType = reMap.get("gateReturnType");
                        String respInfo = reMap.get("gateReturnMessage");
                        if ("S".equals(gateReturnType)) {
                            String returnMessage = reMap.get("businessContext");
                            WriteBankLogLn("银行返回报文中的businessContext：" + returnMessage);
                            String returnbody = decodeMsgToString(p_req.contractDetail.recAct, returnMessage);
                            WriteBankLogLn("解密结果：" + returnbody);
                            Map<String, String> str = (Map<String, String>) JSON.parse(returnbody.toString());

                            String busiType = str.get("busiType");
                            String busiMsg = str.get("busiMsg");
                            String busiCode = str.get("busiCode");
                            if ("S".equals(busiType)) {
                                tmpRetDetail.respCode = "0";
                                JSONObject tmpRetJson = JSONObject.parseObject(returnbody.toString());
                                JSONArray protocolIdList = tmpRetJson.getJSONArray("protocolIdList");
                                String protocolId = ((JSONObject) protocolIdList.get(0)).getString("protocolId");
                                String tmpMsg = ((JSONObject) protocolIdList.get(0)).getString("message");
                                busiCode=((JSONObject) protocolIdList.get(0)).getString("code");
                                tmpRetDetail.respInfo=tmpMsg;
                                SeqData seqData = new SeqData();
                                seqData.ownAct = p_req.contractDetail.recAct;
                                seqData.srcSys = p_req.reqHeader.bankCode;
                                seqData.ownSeq = p_req.contractDetail.askNumber;
                                seqData.oppSeq = protocolId;
                                int rowsAff = seqHelper.insertSeqData(seqData);
                                this.WriteBankLogLn("保存seqdata（protocolId：" + protocolId + "）影响行数：" + rowsAff);
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = busiMsg;
                            }
                            tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", busiCode);

                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = respInfo;
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpStrRet[1];
                    }
                } else if ("02".equals(p_req.contractDetail.step)) {
                    if (padSingleSeq50) {
                        merchantSeq = actItem.merchantId + "_" + p_req.reqHeader.transSeqID + "_02_";
                        merchantSeq = StringHelper.padByByte(merchantSeq, this.getCharset(reqHeader.transType), 50, '0', 'R');
                    }
                    String version = "v1.0";
                    String source = "PC";
                    String merchantNum = actItem.merchantId;
                    Date timeNow = new Date();
                    String transDate = Format.Date8Format.format(timeNow);
                    String transTime = Format.Time9Format.format(timeNow);
                    String transCode = "PAY_T017";// 交易编码 todo
                    String securityType = "SM203";
                    String reserve1 = "";
                    String reserve2 = "";
                    String reserve3 = "";
                    String reserve4 = "";
                    String reserve5 = "";
                    String reserveJson = "";
                    // 业务报文 businessContext String 4096 N 传递给业务系统的报文

                    // 组装业务报文
                    String defaultTradeType = "30010001";
                    String contractId = actItem.getBusCode("auth");
                    String protocolId = seqHelper.getOppSeq(p_req.contractDetail.askNumber, p_req.contractDetail.recAct, p_req.reqHeader.bankCode);
                    String preProtocolIdList = contractId + "^" + protocolId;
                    String draweePhoneNum = p_req.contractDetail.cellPhone;
                    String smVerifyStr = p_req.contractDetail.smsCode;
                    String extendData = "";
                    // 发送给银行的报文
                    Map<String, String> messagetoBank = new HashMap<String, String>();
                    messagetoBank.put("version", version);
                    messagetoBank.put("source", source);
                    messagetoBank.put("merchantNum", merchantNum);
                    messagetoBank.put("merchantSeq", merchantSeq);
                    messagetoBank.put("transDate", transDate);
                    messagetoBank.put("transTime", transTime);
                    messagetoBank.put("transCode", transCode);
                    messagetoBank.put("securityType", securityType);
                    messagetoBank.put("reserve1", reserve1);
                    messagetoBank.put("reserve2", reserve2);
                    messagetoBank.put("reserve3", reserve3);
                    messagetoBank.put("reserve4", reserve4);
                    messagetoBank.put("reserve5", reserve5);
                    messagetoBank.put("reserveJson", reserveJson);
                    messagetoBank.put("defaultTradeType", defaultTradeType);
                    messagetoBank.put("contractId", contractId);
                    messagetoBank.put("preProtocolIdList", preProtocolIdList);
                    messagetoBank.put("draweePhoneNum", draweePhoneNum);
                    messagetoBank.put("smVerifyStr", smVerifyStr);
                    messagetoBank.put("extendData", extendData);
                    messagetoBank.put("postscript", postscript);

                    Map<String, String> submitMap = new HashMap<String, String>();
                    Map<String, String> busiMap = new HashMap<String, String>();
                    splidReqMap(messagetoBank, submitMap, busiMap);
                    submitMap.put("businessContext", encodeMsgToString(p_req.contractDetail.recAct, busiMap));

                    String message = submitMap.toString();
                    WriteBankLogLn("发送给银行的报文：" + message);

                    String tmpUrl = bankFront.getUrl("Pay");
                    String[] tmpStrRet = sendToBank(submitMap, tmpUrl);

                    if (tmpStrRet[0].length() == 0) {
                        WriteBankLogLn("银行返回的报文：" + tmpStrRet[1]);
                        Map<String, String> reMap = (Map<String, String>) JSON.parse(tmpStrRet[1].toString());

                        WriteBankLogLn("解析后银行返回的报文map形式：" + reMap);
                        WriteBankLogLn("解析后银行返回的报文：" + reMap.toString());
                        String gateReturnType = reMap.get("gateReturnType");
                        String respInfo = reMap.get("gateReturnMessage");
                        tmpRetDetail.authCode = p_req.contractDetail.authCode;
                        if ("S".equals(gateReturnType)) {
                            String returnMessage = reMap.get("businessContext");
                            WriteBankLogLn("银行返回报文中的businessContext：" + returnMessage);
                            String returnbody = decodeMsgToString(p_req.contractDetail.recAct, returnMessage);
                            WriteBankLogLn("解密结果：" + returnbody);
                            Map<String, String> str = (Map<String, String>) JSON.parse(returnbody.toString());

                            String busiType = str.get("busiType");
                            String busiMsg = str.get("busiMsg");
                            String busiCode = str.get("busiCode");
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = busiMsg;
                            if ("S".equals(busiType)) {
                                tmpRetDetail.signState = ContractState.SUCCESS;
                            } else {
                                tmpRetDetail.signState = ContractState.FAIL;
                            }
                            if(StringHelper.isNullOrEmpty(tmpRetDetail.authCode)){
                                tmpRetDetail.authCode=protocolId;
                            }
                            tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", busiCode);
                            tmpRetDetail.newAuthCode = protocolId;
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = respInfo;
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpStrRet[1];
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "未能识别的step：" + p_req.contractDetail.step;
                    retAts.writeRetDetail(tmpRetDetail);
                    return retAts;
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号[" + p_req.contractDetail.recAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }finally{
        	if(seqHelper!=null){
        		seqHelper.close();
        	}
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsContract upContract(ReqContract p_req) throws Exception {
        return null;
    }

    @Override
    public RetAtsContract qryContract(ReqContract p_reqQry) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_reqQry.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_reqQry.contractDetail.askNumber;
        tmpRetDetail.respCode = "0";
        tmpRetDetail.respInfo = "未签约!";
        tmpRetDetail.signState = ContractState.UNSIGNED;
        tmpRetDetail.signConfirmType = "2";
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsQryBatContract qryBatContract(ReqQryBatContract p_reqQry) throws Exception {
        return null;
    }
}
